using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;

namespace Dogfight2008.Tests
{
  [TestFixture]
  public class GameDBFixture
  {
    [Test, ExpectedException]
    public void AtLeastOneTypeNeeded()
    {
      GameDB db = new GameDB();
    }

    GameDB StringDB()
    {
      return new GameDB(typeof(string));
    }

    GameDB IntDB()
    {
      return new GameDB(typeof(int));
    }

    [Test]
    public void Add()
    {
      GameDB db = IntDB();
      db.Add(1);
    }

    [Test]
    public void Add_NullIsIgnored()
    {
      GameDB db = IntDB();
      db.Add(null);
    }

    [Test]
    public void Count() {
      GameDB db = IntDB();
      db.Add(1);
      db.Add(2);
      Assert.AreEqual(2, db.Count(typeof(int)));
    }

    [Test]
    public void RemoveNonExistentIsOK()
    {
      GameDB db = IntDB();
      db.Remove(2);
    }

    [Test]
    public void Add2Delete1()
    {
      GameDB db = StringDB();
      string obj1 = "olof";
      string obj2 = "bjarnason";
      db.Add(obj1);
      db.Add(obj2);
      db.Remove(obj1);
      Assert.AreEqual(1, db.Count(typeof(string)));
    }

    [Test]
    public void ObjectIsOK()
    {
      GameDB db = new GameDB(typeof(object));
    }

    [Test]
    public void InterfaceIsOK()
    {
      GameDB db = new GameDB(typeof(IList<int>));
    }

    [Test,ExpectedException]
    public void CannotCountUnknownType()
    {
      GameDB db = IntDB();
      db.Count(typeof(string));
    }

    [Test]
    public void AddRange()
    {
      GameDB db = IntDB();
      db.AddRange(List(1, 2, 3));
    }

    List<object> List(params object[] objs)
    {
      return new List<object>(objs);
    }

    [Test]
    public void CountCountsCorrectType()
    {
      GameDB db = new GameDB(typeof(string), typeof(int));
      db.AddRange(List("olof", "bjarnason"));
      db.AddRange(List(1, 2, 3));
      Assert.AreEqual(2, db.Count(typeof(string)));
      Assert.AreEqual(3, db.Count(typeof(int)));
    }

    [Test]
    public void Select()
    {
      GameDB db = new GameDB(typeof(string));
      List<object> exp = List("olof", "bjarnason");
      db.AddRange(exp);
      List<string> res = new List<string>();
      foreach(string s in db.Select(typeof(string)))
        res.Add(s);
      CollectionAssert.AreEqual(exp, res);
    }

    [Test, ExpectedException]
    public void Select_UnknownType()
    {
      GameDB db = new GameDB(typeof(string));
      db.Select(typeof(int));
    }

    class A { }
    class B : A { }

    [Test]
    public void HowInheritageCountingWorks()
    {
      GameDB db = new GameDB(typeof(A), typeof(B));
      db.AddRange(List(new A(), new A()));
      db.AddRange(List(new B()));
      Assert.AreEqual(3, db.Count(typeof(A)));
      Assert.AreEqual(1, db.Count(typeof(B)));
    }
  }
}
